home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
9-Digit Zip Code Directory
/
9-Digit Zip Code Directory (American Business Information) (ABIZIP-12).ISO
/
z4src.zip
/
Z4Z4EX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-27
|
9KB
|
310 lines
//----------------------------------------------------------------------------
// MODULE DESCRIPTION
//
// Module: Z4Z4ex.c
// Title: ZIP+4 Engine
// Notice: John M. Weeder
// Copyright (c) 1993. All rights reserved.
// This module contains proprietary information and should be
// treated as confidential.
//
//----------------------------------------------------------------------------
// MAINTENANCE HISTORY
//
// $Workfile$
// $Revision$
// $Author$
// $Date$
// $Log$
//
//----------------------------------------------------------------------------
// MODULE NARRATIVE
//
//
// This module contains the expander for the ZIP+4 file.
// This module should not use any global variables since it must be
// re-entrant.
//
// The code in this module should be written entirely in C.
// Do not use any C++ constructs.
//
// This module is portable to:
// DOS 3.X+
// MS Windows 3.X+
// OS/2 2.X+
// OS/2 2.0 PM
// SCO UNIX.
//
// The following compilers are supported:
// MSC 6.0A
// MSC/C++ 7.0
// Borland C++ 3.1 for DOS
// Borland C++ 1.0 for OS/2 2.X
// SCO UNIX cc
//
//----------------------------------------------------------------------------
#include <z4.h>
//----------------------------------------------------------------------------
// Description: Read a compressed record from the output buffer.
// Parameters: pblk Decoder data structure
// pz4 Expanded record
// Returns: TRUE if successful. FALSE if not more records found to
// decode.
//----------------------------------------------------------------------------
BOOL FN_E Z4Z4Expand(PZ4_Z4_BLK pblk, PZ4_Z4 pz4)
{
PBYTE pb;
SIZET cb;
BYTE b, b2 = 0;
USHORT us1;
SIZET cString;
PCSZ pcszNumeric;
//
// Set up
//
Assert(pblk && pz4);
if (pblk->cbNext >= pblk->cb - 1) // Need at least 2 bytes for a record
return FALSE;
Assert(pblk->cbNext <= pblk->cb); // THIS SHOULD NOT HAPPEN
pb = pblk->pb + pblk->cbNext;
if (*(PUSHORT)pb == 0) // Block not full, but no more records
{
pblk->cbNext = pblk->cb;
return FALSE;
}
//
// Decode this record
//
us1 = *(PUSHORT)pb; // Read bit flags
pb += sizeof(USHORT);
if (us1 & Z4_BYTE_FOLLOWS)
b2 = *pb++;
if (us1 & Z41_UNIT_REC_TYPE)
{
b = *pb++;
pblk->z4.rectype = (Z4_TYPE)(b & 0x07);
pblk->z4.unit = (Z4_UNIT)(b >> 3);
}
if (us1 & Z41_DIR)
{
b = *pb++;
pblk->z4.postdir = (Z4_DIR)(b & 0x0F);
pblk->z4.predir = (Z4_DIR)(b >> 4);
}
if (us1 & Z41_CODES)
{
b = *pb++;
pblk->z4.alt = (Z4_ALT)(b & 0x03);
pblk->z4.pricode = (Z4_CODE)((b >> 2) & 0x03);
pblk->z4.seccode = (Z4_CODE)((b >> 4) & 0x03);
pblk->z4.fOrdinal = (BOOL)(((b >> 6) & 0x01) != 0);
}
if (us1 & Z41_PRI_LO)
{
StringDecode(pblk->pcache, pb, &cString, pblk->z4.szPriLo);
pb += cString;
}
if (us1 & Z41_PRI_DELTA_LO)
{
BYTE bDelta = *pb++;
LONG lPriLo = atol(pblk->z4.szPriLo);
sprintf(pblk->z4.szPriLo, "%ld", (LONG)(lPriLo + (LONG)bDelta));
}
if (us1 & Z41_PRI_HI)
{
StringDecode(pblk->pcache, pb, &cString, pblk->z4.szPriHi);
pb += cString;
}
if (us1 & Z41_PRI_DELTA_HI)
{
BYTE bDelta = *pb++;
LONG lPriLo = atol(pblk->z4.szPriLo);
sprintf(pblk->z4.szPriHi, "%ld", (LONG)(lPriLo + (LONG)bDelta));
}
if (us1 & Z41_SEC_LO)
{
StringDecode(pblk->pcache, pb, &cString, pblk->z4.szSecLo);
pb += cString;
}
if (us1 & Z41_SEC_HI)
{
StringDecode(pblk->pcache, pb, &cString, pblk->z4.szSecHi);
pb += cString;
}
if (us1 & Z41_PRI_NAME)
{
StringDecode(pblk->pcache, pb, &cString, pblk->z4.szPriName);
pb += cString;
}
if (us1 & Z41_ADDON_LO)
{
strb2a(pb, MAX_ADDON_BCD, pblk->z4.szAddonLo, MAX_ADDON, TRUE);
pb += MAX_ADDON_BCD;
}
if (us1 & Z41_ADDON_HI)
{
strb2a(pb, MAX_ADDON_BCD, pblk->z4.szAddonHi, MAX_ADDON, TRUE);
pb += MAX_ADDON_BCD;
}
if (us1 & Z41_SUFFIX1)
{
pblk->z4.suffix1 = (Z4_SUFFIX)*pb++;
}
if (us1 & Z41_SUFFIX2)
{
pblk->z4.suffix2 = (Z4_SUFFIX)*pb++;
}
if (b2 & Z42_SEC_NAME)
{
StringDecode(pblk->pcache, pb, &cString, pblk->z4.szSecName);
pb += cString;
}
if (b2 & Z42_ZIP5)
{
strb2a(pb, MAX_ZIP5_BCD, pblk->z4.szZip5, MAX_ZIP5, TRUE);
pb += MAX_ZIP5_BCD;
}
if (b2 & Z42_CRIS)
{
StringDecode(pblk->pcache, pb, &cString, pblk->z4.szCris);
pb += cString;
}
if (b2 & Z42_LAST_LINE)
{
strb2a(pb, MAX_LAST_LINE_BCD, pblk->z4.szLastLine, MAX_LAST_LINE, TRUE);
pb += MAX_LAST_LINE_BCD;
}
if (b2 & Z42_FINANCE)
{
strb2a(pb, MAX_FINANCE_BCD, pblk->z4.szFinance, MAX_FINANCE, TRUE);
pb += MAX_FINANCE_BCD;
}
//
// Handle special bits
//
if (us1 & Z41_ADDON_LO_HI)
strcpy(pblk->z4.szAddonHi,pblk->z4.szAddonLo);
if (b2 & Z42_PRI_LO_HI)
strcpy(pblk->z4.szPriHi,pblk->z4.szPriLo);
if (b2 & Z42_SEC_LO_HI)
strcpy(pblk->z4.szSecHi,pblk->z4.szSecLo);
if (b2 & Z42_SEC_NAME_BLANK)
pblk->z4.szSecName[0] = '\0';
//
// Do some cleanup work
//
if (strcmp(pblk->z4.szAddonHi, "0000") == 0)
strcpy(pblk->z4.szAddonHi, "ND");
if (strcmp(pblk->z4.szAddonLo, "0000") == 0)
strcpy(pblk->z4.szAddonLo, "ND");
if (pblk->z4.szSecLo[0] == '-')
pblk->z4.szSecLo[0] = '0';
if (pblk->z4.szSecHi[0] == '-')
pblk->z4.szSecHi[0] = '0';
if (pblk->z4.szPriLo[0] == '-')
pblk->z4.szPriLo[0] = '0';
if (pblk->z4.szPriHi[0] == '-')
pblk->z4.szPriHi[0] = '0';
switch (pblk->z4.rectype)
{
case Z4_TYPE_POB:
strcpy(pblk->z4.szPriName, "PO BOX");
break;
case Z4_TYPE_GD:
strcpy(pblk->z4.szPriName, "GENERAL DELIVERY");
break;
case Z4_TYPE_PM:
strcpy(pblk->z4.szPriName, "POSTMASTER");
break;
}
// Check if primary name of record is all numeric
pblk->z4.fNumeric = TRUE;
pcszNumeric = pblk->z4.szPriName;
for (; pcszNumeric[0]; ++pcszNumeric)
if (!isdigit(pcszNumeric[0]))
{
pblk->z4.fNumeric = FALSE;
break;
}
//
// Done, clean up
//
cb = (SIZET)(pb - pblk->pb);
Assert(cb <= pblk->cb);
pblk->cbNext = cb;
*pz4 = pblk->z4; // Return a copy of the current record
return TRUE;
}
//----------------------------------------------------------------------------
// Description: Initialize city/state expander
// Parameters: pblk City/state decoder data structure
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_E Z4Z4ExpandInitialize(PZ4_Z4_BLK pblk)
{
Assert(pblk);
memset(pblk, 0, sizeof(Z4_Z4_BLK));
pblk->pcache = StringCreate(Z4_Z4_WORD_CACHE, 0);
if (pblk->pcache == NULL)
return FALSE;
return TRUE;
}
//----------------------------------------------------------------------------
// Description: Reset expander to decode another block of data
// Parameters: pblk Decoder data structure
// pb Buffer containing compressed data.
// cb Size of buffer.
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_E Z4Z4ExpandReset(PZ4_Z4_BLK pblk, PBYTE pb, SIZET cb)
{
Assert(pblk);
StringReset(pblk->pcache);
memset(&pblk->z4, 0, sizeof(Z4_Z4));
pblk->z4.seccode = Z4_BOTH; // Set default record characteristics
pblk->z4.pricode = Z4_BOTH;
pblk->z4.rectype = Z4_TYPE_ST;
pblk->z4.predir = Z4_DIR_BLANK;
pblk->z4.postdir = Z4_DIR_BLANK;
pblk->z4.unit = Z4_UNIT_BLANK;
pblk->z4.alt = Z4_ALT_B;
pblk->z4.suffix1 = 0;
pblk->z4.suffix2 = 0;
pblk->pb = pb; // Set decoding pointers
pblk->cb = cb;
pblk->cbNext = 0;
return TRUE;
}
//----------------------------------------------------------------------------
// Description: Terminate city/state expander.
// Parameters: pblk City/state decoder data structure
// Returns: TRUE if successful.
//----------------------------------------------------------------------------
BOOL FN_E Z4Z4ExpandTerminate(PZ4_Z4_BLK pblk)
{
Assert(pblk);
if (pblk->pcache) // Close word cache
WordDestroy(pblk->pcache);
memset(pblk, 0, sizeof(Z4_Z4_BLK));
return TRUE;
}
//----------------------------------------------------------------------------
//------------------------------- End of File --------------------------------
//----------------------------------------------------------------------------